#!/usr/bin/env python3
"""
HTML语法高亮器
支持HTML标签、属性、CSS样式、JavaScript代码等
"""

from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor, QFont

class HTMLHighlighter(QSyntaxHighlighter):
    """HTML语法高亮器"""
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.highlighting_rules = []
        self.setup_rules()
    
    def setup_rules(self):
        """设置HTML语法高亮规则"""
        
        # HTML标签格式 - 蓝色
        tag_format = QTextCharFormat()
        tag_format.setForeground(QColor('#569CD6'))  # 蓝色
        tag_format.setFontWeight(QFont.Bold)
        
        # HTML标签（开始和结束标签）
        tag_pattern = QRegExp(r'</?\s*[a-zA-Z][a-zA-Z0-9]*\s*/?>')
        self.highlighting_rules.append((tag_pattern, tag_format))
        
        # 属性名格式 - 橙色
        attribute_name_format = QTextCharFormat()
        attribute_name_format.setForeground(QColor('#CE9178'))  # 橙色
        
        # HTML属性名
        attribute_name_pattern = QRegExp(r'\b[a-zA-Z_][a-zA-Z0-9_-]*\s*=')
        self.highlighting_rules.append((attribute_name_pattern, attribute_name_format))
        
        # 属性值格式 - 绿色
        attribute_value_format = QTextCharFormat()
        attribute_value_format.setForeground(QColor('#6A8759'))  # 绿色
        
        # HTML属性值（单引号和双引号）
        attribute_value_pattern = QRegExp(r'=\s*["\'][^"\']*["\']')
        self.highlighting_rules.append((attribute_value_pattern, attribute_value_format))
        
        # 注释格式 - 灰色
        comment_format = QTextCharFormat()
        comment_format.setForeground(QColor('#808080'))  # 灰色
        comment_format.setFontItalic(True)
        
        # HTML注释
        comment_pattern = QRegExp(r'<!--[^>]*-->')
        self.highlighting_rules.append((comment_pattern, comment_format))
        
        # DOCTYPE声明格式 - 紫色
        doctype_format = QTextCharFormat()
        doctype_format.setForeground(QColor('#B5CEA8'))  # 紫色
        doctype_format.setFontWeight(QFont.Bold)
        
        # DOCTYPE声明
        doctype_pattern = QRegExp(r'<!DOCTYPE[^>]*>')
        self.highlighting_rules.append((doctype_pattern, doctype_format))
        
        # 特殊标签格式 - 青色
        special_tag_format = QTextCharFormat()
        special_tag_format.setForeground(QColor('#4EC9B0'))  # 青色
        special_tag_format.setFontWeight(QFont.Bold)
        
        # 特殊标签（script, style, meta等）
        special_tags = ['script', 'style', 'meta', 'link', 'title', 'base']
        for tag in special_tags:
            pattern = QRegExp(r'</?\s*' + tag + r'\s*/?>')
            self.highlighting_rules.append((pattern, special_tag_format))
        
        # CSS样式格式 - 浅蓝色
        css_format = QTextCharFormat()
        css_format.setForeground(QColor('#9CDCFE'))  # 浅蓝色
        
        # CSS属性名（在style标签或属性中）
        css_property_pattern = QRegExp(r'\b[a-zA-Z-]+\s*:')
        self.highlighting_rules.append((css_property_pattern, css_format))
        
        # CSS值格式 - 浅绿色
        css_value_format = QTextCharFormat()
        css_value_format.setForeground(QColor('#B5CEA8'))  # 浅绿色
        
        # CSS属性值
        css_value_pattern = QRegExp(r':\s*[^;]+;')
        self.highlighting_rules.append((css_value_pattern, css_value_format))
        
        # JavaScript关键字格式 - 橙色
        js_keyword_format = QTextCharFormat()
        js_keyword_format.setForeground(QColor('#CE9178'))  # 橙色
        js_keyword_format.setFontWeight(QFont.Bold)
        
        # JavaScript关键字（在script标签中）
        js_keywords = [
            'function', 'var', 'let', 'const', 'if', 'else', 'for', 'while', 'do', 'switch',
            'case', 'break', 'continue', 'return', 'try', 'catch', 'finally', 'throw',
            'class', 'extends', 'import', 'export', 'default', 'async', 'await', 'new',
            'this', 'super', 'typeof', 'instanceof', 'in', 'delete', 'void', 'yield'
        ]
        
        for keyword in js_keywords:
            pattern = QRegExp(r'\b' + keyword + r'\b')
            self.highlighting_rules.append((pattern, js_keyword_format))
        
        # JavaScript函数名格式 - 蓝色
        js_function_format = QTextCharFormat()
        js_function_format.setForeground(QColor('#4E9AEF'))  # 蓝色
        
        # JavaScript函数名
        js_function_pattern = QRegExp(r'\bfunction\s+([a-zA-Z_][a-zA-Z0-9_]*)')
        self.highlighting_rules.append((js_function_pattern, js_function_format))
        
        # JavaScript字符串格式 - 绿色
        js_string_format = QTextCharFormat()
        js_string_format.setForeground(QColor('#6A8759'))  # 绿色
        
        # JavaScript字符串（单引号和双引号）
        js_string_pattern = QRegExp(r'["\'][^"\']*["\']')
        self.highlighting_rules.append((js_string_pattern, js_string_format))
        
        # JavaScript注释格式 - 灰色
        js_comment_format = QTextCharFormat()
        js_comment_format.setForeground(QColor('#808080'))  # 灰色
        js_comment_format.setFontItalic(True)
        
        # JavaScript单行注释
        js_single_comment_pattern = QRegExp(r'//[^\n]*')
        self.highlighting_rules.append((js_single_comment_pattern, js_comment_format))
        
        # 实体引用格式 - 粉色
        entity_format = QTextCharFormat()
        entity_format.setForeground(QColor('#CE9178'))  # 粉色
        
        # HTML实体引用
        entity_pattern = QRegExp(r'&[a-zA-Z]+;')
        self.highlighting_rules.append((entity_pattern, entity_format))
        
        # 数字格式 - 紫色
        number_format = QTextCharFormat()
        number_format.setForeground(QColor('#B5CEA8'))  # 紫色
        
        # 数字（在CSS和JS中）
        number_pattern = QRegExp(r'\b\d+\.?\d*\b')
        self.highlighting_rules.append((number_pattern, number_format))
    
    def highlightBlock(self, text):
        """高亮文本块"""
        # 先处理多行注释（需要特殊处理）
        self.highlight_multiline_comments(text)
        
        # 然后处理其他规则
        for pattern, format_ in self.highlighting_rules:
            expression = QRegExp(pattern)
            index = expression.indexIn(text)
            while index >= 0:
                length = expression.matchedLength()
                # 检查是否已经在注释中
                if self.currentBlockState() != 1:
                    self.setFormat(index, length, format_)
                index = expression.indexIn(text, index + length)
    
    def highlight_multiline_comments(self, text):
        """处理多行注释高亮"""
        # 获取前一个块的状态
        previous_state = self.previousBlockState()
        
        # 注释格式
        comment_format = QTextCharFormat()
        comment_format.setForeground(QColor('#808080'))  # 灰色
        comment_format.setFontItalic(True)
        
        start_index = 0
        
        # 如果前一个块在注释中，继续高亮
        if previous_state == 1:
            start_index = 0
            self.setFormat(0, len(text), comment_format)
            
            # 查找注释结束位置
            end_pattern = QRegExp(r'-->')
            end_index = end_pattern.indexIn(text)
            if end_index >= 0:
                # 注释结束，重置状态
                self.setCurrentBlockState(0)
            else:
                # 注释继续到下一行
                self.setCurrentBlockState(1)
            return
        
        # 查找注释开始
        start_pattern = QRegExp(r'<!--')
        start_index = start_pattern.indexIn(text)
        
        while start_index >= 0:
            # 查找注释结束
            end_pattern = QRegExp(r'-->')
            end_index = end_pattern.indexIn(text, start_index + 4)
            
            if end_index == -1:
                # 注释跨越多行
                self.setFormat(start_index, len(text) - start_index, comment_format)
                self.setCurrentBlockState(1)
                break
            else:
                # 单行内的注释
                self.setFormat(start_index, end_index - start_index + 3, comment_format)
                start_index = end_pattern.indexIn(text, end_index + 3)